package com.loe.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.Html;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import org.xml.sax.XMLReader;

import java.util.HashMap;

@SuppressLint("AppCompatCustomView")
public class HtmlTextView extends TextView
{
    private HashMap<String, OnClickListener> clickMap;

    private String baseText = "";

    private Context context;

    public HtmlTextView(Context context)
    {
        super(context);
    }

    public HtmlTextView(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
        init(context);
    }

    public HtmlTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @SuppressLint("NewApi")
    public HtmlTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)
    {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    private void init(Context context)
    {
        this.context = context;
        setText(super.getText().toString());
    }

    public void replace(String oldS, String newS)
    {
        setText(baseText.replace(oldS, newS));
    }

    public void setText(String text)
    {
        baseText = text;
        super.setText(Html.fromHtml(text
                .replace("[", "<")
                .replace("]", ">")
                .replace("\n", "<br/>")
                .replace("□", "&nbsp;"), new Html.ImageGetter()
        {
            @Override
            public Drawable getDrawable(String s)
            {
                if(s.startsWith("mipmap:"))
                {
                    String name = s.replace("mipmap:","");
                    int resId = context.getResources().getIdentifier(name, "mipmap", context.getPackageName());
                    if(resId == 0) return null;
                    Drawable drawable = ContextCompat.getDrawable(context, resId);
                    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                    return drawable;
                }else
                if(s.startsWith("drawable:"))
                {
                    String name = s.replace("drawable:","");
                    int resId = context.getResources().getIdentifier(name, "drawable", context.getPackageName());
                    if(resId != 0) return context.getResources().getDrawable(resId);
                }
                return null;
            }
        }, new Html.TagHandler()
        {
            private int sStart = 0;
            private int onStart = 0;

            @Override
            public void handleTag(boolean opening, String s, Editable editable, XMLReader xmlReader)
            {
                // 字体大小
                if (s.length() > 1 && s.startsWith("s"))
                {
                    if (opening)
                    {
                        sStart = editable.length();
                        return;
                    }
                    try
                    {
                        int size = dp_Px(Integer.parseInt(s.replace("s", "")));
                        editable.setSpan(new AbsoluteSizeSpan(size), sStart, editable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    } catch (Exception e)
                    {
                    }
                }
                // 点击
                else if (s.startsWith("on"))
                {
                    setMovementMethod(LinkMovementMethod.getInstance());
                    if (opening)
                    {
                        onStart = editable.length();
                        return;
                    }
                    final String tag = s;
                    ClickableSpan clickableSpan = new ClickableSpan()
                    {
                        @Override
                        public void updateDrawState(@NonNull TextPaint ds)
                        {
                            ds.setUnderlineText(false);
                        }

                        @Override
                        public void onClick(@NonNull View view)
                        {
                            if (clickMap != null)
                            {
                                OnClickListener listener = clickMap.get(tag);
                                if (listener != null)
                                {
                                    listener.onClick(view);
                                }
                            }
                        }
                    };
                    editable.setSpan(clickableSpan, onStart, editable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }));

        isAlpha = isClickable();
    }

    public static int dp_Px(double dp)
    {
        return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
    }

    public void addOnClickListener(String tag, OnClickListener listener)
    {
        if (clickMap == null)
        {
            clickMap = new HashMap<>();
        }
        clickMap.put(tag, listener);
    }

    public void removeOnClickListener(String tag)
    {
        if (clickMap != null)
        {
            clickMap.remove(tag);
        }
    }

    public void clearOnClickListener()
    {
        clickMap = null;
    }

    private boolean isAlpha = false;

    @Override
    protected void dispatchSetPressed(boolean pressed)
    {
        if(isAlpha) setAlpha(pressed || !isEnabled() ? 0.65f : 1);
        super.dispatchSetPressed(pressed);
    }

    @Override
    public void setEnabled(boolean enabled)
    {
        if(isAlpha) setAlpha(enabled ? 1 : 0.65f);
        super.setEnabled(enabled);
    }

    //    [font color='#'][/font]
    //    [u][/u]
    //    [b][/b]
    //    [i][/i]
    //    [s][/s]
    //    [on][/on]
}